﻿package com.duartepeixinho.pTween.plugins 
{
	import com.duartepeixinho.pTween.core.tweenObj;
	import com.duartepeixinho.pTween.core.tweenEquations;
	import flash.filters.BevelFilter;
	import flash.filters.BlurFilter;
	import flash.filters.DropShadowFilter;
	import flash.filters.GlowFilter;

	/**
	 * pTween v1.1
	 * @author Duarte Peixinho
	 */
	public class PluginFilter extends PluginFeature
	{		
		public static function register():void {
			registerPlugin("PluginFilter");			
			registerProperties();
		}
		public static function registerProperties():void {		
			registerProperty("blurFilter");
			registerProperty("glowFilter");		
			registerProperty("dropShadowFilter");
			registerProperty("bevelFilter");
		}
		
		public static function update(target:tweenObj, time:Number):void {
			
			// new filters array
			var newFilters:Array = new Array();
			var oldGlowFilter:GlowFilter;
			var glowFilter:GlowFilter;
			var oldBlurFilter:BlurFilter;
			var blurFilter:BlurFilter;	
			var oldDropShadowFilter:DropShadowFilter;
			var dropShadowFilter:DropShadowFilter;
			var oldBevelFilter:BevelFilter;
			var bevelFilter:BevelFilter;
			
			
			// get old filter
			if (target.target) {
				newFilters = target.target.filters;
				// set initial filters			
				for each(var filter:* in target.target.filters) {
					// blurFilter
					if (filter is BlurFilter) {						
						if (!target.specialInitProperties["blurFilter"]) target.specialInitProperties["blurFilter"] = filter;
						oldBlurFilter = filter;
					}
					// glowFilter
					if (filter is GlowFilter) {
						if (!target.specialInitProperties["glowFilter"]) target.specialInitProperties["glowFilter"] = filter;
						oldGlowFilter = filter;
					}
					// dropShadowFilter
					if (filter is DropShadowFilter) {
						if (!target.specialInitProperties["dropShadowFilter"]) target.specialInitProperties["dropShadowFilter"] = filter;
						oldDropShadowFilter = filter;
					}
					// bevelFilter
					if (filter is BevelFilter) {
						if (!target.specialInitProperties["bevelFilter"]) target.specialInitProperties["bevelFilter"] = filter;
						oldBevelFilter = filter;
					}
				}	
				if (!oldBlurFilter) oldBlurFilter = new BlurFilter(0, 0, 1);
				if (!oldGlowFilter) oldGlowFilter = new GlowFilter(16711680, 1, 0, 0, 2, 1);
				if (!oldDropShadowFilter) oldDropShadowFilter = new DropShadowFilter(0, 45, 0, 1, 0, 0, 0, 1);
				if (!oldBevelFilter) oldBevelFilter = new BevelFilter(0, 45, 16777215, 1, 0, 1, 0, 0, 0, 1);
			
			
			for (var s:String in target.specialProperties) {
				var p:String;
					switch(s) {
						/* BLURFILTER */
						case "blurFilter":						
							// set initial blurFilter						
							if (!target.specialInitProperties["blurFilter"]) {							
								target.specialInitProperties["blurFilter"] = oldBlurFilter;							
							}
							blurFilter = oldBlurFilter;
							
							for (p in target.specialProperties[s]) {
								if (p == "blurX") {
									blurFilter.blurX = tweenEquations.calculateEquation(target.easing, time, target.specialInitProperties["blurFilter"]["blurX"], target.specialProperties[s][p] - target.specialInitProperties["blurFilter"]["blurX"], target.duration);																	
								}
								if (p == "blurY") {
									blurFilter.blurY=tweenEquations.calculateEquation(target.easing, time, target.specialInitProperties["blurFilter"]["blurY"], target.specialProperties[s][p] - target.specialInitProperties["blurFilter"]["blurY"], target.duration);
								}
								if (p == "quality") {
									blurFilter.quality = target.specialProperties[s][p];
								}
								
								// set filter array
								if (target.target)
								setFilterArray(blurFilter,BlurFilter,newFilters);
							}						
						break;
						
						/* GLOWFILTER */
						case "glowFilter":
							// set initial glowFilter
							if (!target.specialInitProperties["glowFilter"]) {
								target.specialInitProperties["glowFilter"] = oldGlowFilter;
							}
							
							glowFilter = oldGlowFilter;
							
							for (p in target.specialProperties[s]) {
								if (p == "blurX") {
									glowFilter.blurX=tweenEquations.calculateEquation(target.easing, time, target.specialInitProperties["glowFilter"]["blurX"], target.specialProperties[s][p] - target.specialInitProperties["glowFilter"]["blurX"], target.duration);
								}
								if (p == "blurY") {
									glowFilter.blurY = tweenEquations.calculateEquation(target.easing, time, target.specialInitProperties["glowFilter"]["blurY"], target.specialProperties[s][p] - target.specialInitProperties["glowFilter"]["blurY"], target.duration);
								}
								if (p == "alpha") {
									glowFilter.alpha = tweenEquations.calculateEquation(target.easing, time, target.specialInitProperties["glowFilter"]["alpha"], target.specialProperties[s][p] - target.specialInitProperties["glowFilter"]["alpha"], target.duration);
								}
								if (p == "strength") {
									glowFilter.strength = tweenEquations.calculateEquation(target.easing, time, target.specialInitProperties["glowFilter"]["strength"], target.specialProperties[s][p] - target.specialInitProperties["glowFilter"]["strength"], target.duration);									
								}
								if (p == "color") {
									glowFilter.color = colorChange(target.specialInitProperties["glowFilter"]["color"], target.specialProperties[s][p], target.easing, time, target.duration);																		
								}
								if (p == "quality") glowFilter.quality = target.specialProperties[s][p];
								if (p == "knockout") glowFilter.knockout = target.specialProperties[s][p];																
								if (p == "inner") glowFilter.inner = target.specialProperties[s][p];								
							}	
							// set filter array
							setFilterArray(glowFilter,GlowFilter,newFilters);									
						break;
						
						/* DROPSHADOWFILTER */
						case "dropShadowFilter":
							// set initial dropShadowFilter
							if (!target.specialInitProperties["dropShadowFilter"]) {
								target.specialInitProperties["dropShadowFilter"] = oldDropShadowFilter;
							}
							
							dropShadowFilter = oldDropShadowFilter;
							
							for (p in target.specialProperties[s]) {
								if (p == "blurX") {									
									dropShadowFilter.blurX = tweenEquations.calculateEquation(target.easing, time, target.specialInitProperties["dropShadowFilter"]["blurX"], target.specialProperties[s][p] - target.specialInitProperties["dropShadowFilter"]["blurX"], target.duration);
								}
								if (p == "blurY") {
									dropShadowFilter.blurY=tweenEquations.calculateEquation(target.easing, time, target.specialInitProperties["dropShadowFilter"]["blurY"], target.specialProperties[s][p] - target.specialInitProperties["dropShadowFilter"]["blurY"], target.duration);
								}
								if (p == "alpha") {
									dropShadowFilter.alpha=tweenEquations.calculateEquation(target.easing, time, target.specialInitProperties["dropShadowFilter"]["alpha"], target.specialProperties[s][p] - target.specialInitProperties["dropShadowFilter"]["alpha"], target.duration);
								}
								if (p == "angle") {
									dropShadowFilter.angle=tweenEquations.calculateEquation(target.easing, time, target.specialInitProperties["dropShadowFilter"]["angle"], target.specialProperties[s][p] - target.specialInitProperties["dropShadowFilter"]["angle"], target.duration);
								}
								if (p == "distance") {
									dropShadowFilter.distance=tweenEquations.calculateEquation(target.easing, time, target.specialInitProperties["dropShadowFilter"]["distance"], target.specialProperties[s][p] - target.specialInitProperties["dropShadowFilter"]["distance"], target.duration);
								}
								if (p == "strength") {
									dropShadowFilter.strength=tweenEquations.calculateEquation(target.easing, time, target.specialInitProperties["dropShadowFilter"]["strength"], target.specialProperties[s][p] - target.specialInitProperties["dropShadowFilter"]["strength"], target.duration);
								}
								if (p == "color") {
									dropShadowFilter.color = colorChange(target.specialInitProperties["dropShadowFilter"]["color"], target.specialProperties[s][p], target.easing, time, target.duration);
								}
								if (p == "quality") dropShadowFilter.quality = target.specialProperties[s][p];
								if (p == "knockout") dropShadowFilter.knockout = target.specialProperties[s][p];																
								if (p == "inner") dropShadowFilter.inner = target.specialProperties[s][p];
								
								// set filter array
								setFilterArray(dropShadowFilter,DropShadowFilter,newFilters);	
							}
						break;
						
						/* BEVELFILTER */
						case "bevelFilter":
							// set initial bevelFilter
							if (!target.specialInitProperties["bevelFilter"]) {
								target.specialInitProperties["bevelFilter"] = oldBevelFilter;
							}
							
							bevelFilter = oldBevelFilter;
							
							for (p in target.specialProperties[s]) {
								if (p == "blurX") {									
									bevelFilter.blurX = tweenEquations.calculateEquation(target.easing, time, target.specialInitProperties["bevelFilter"]["blurX"], target.specialProperties[s][p] - target.specialInitProperties["bevelFilter"]["blurX"], target.duration);
								}
								if (p == "blurY") {
									bevelFilter.blurY=tweenEquations.calculateEquation(target.easing, time, target.specialInitProperties["bevelFilter"]["blurY"], target.specialProperties[s][p] - target.specialInitProperties["bevelFilter"]["blurY"], target.duration);
								}
								if (p == "angle") {
									bevelFilter.angle=tweenEquations.calculateEquation(target.easing, time, target.specialInitProperties["bevelFilter"]["angle"], target.specialProperties[s][p] - target.specialInitProperties["bevelFilter"]["angle"], target.duration);
								}
								if (p == "distance") {
									bevelFilter.distance=tweenEquations.calculateEquation(target.easing, time, target.specialInitProperties["bevelFilter"]["distance"], target.specialProperties[s][p] - target.specialInitProperties["bevelFilter"]["distance"], target.duration);
								}
								if (p == "strength") {
									bevelFilter.strength=tweenEquations.calculateEquation(target.easing, time, target.specialInitProperties["bevelFilter"]["strength"], target.specialProperties[s][p] - target.specialInitProperties["bevelFilter"]["strength"], target.duration);
								}
								if (p == "highlightAlpha") {
									bevelFilter.highlightAlpha = tweenEquations.calculateEquation(target.easing, time, target.specialInitProperties["bevelFilter"]["highlightAlpha"], target.specialProperties[s][p] - target.specialInitProperties["bevelFilter"]["highlightAlpha"], target.duration);
								}
								if (p == "highlightColor") {
									bevelFilter.highlightColor = colorChange(target.specialInitProperties["bevelFilter"]["highlightColor"], target.specialProperties["bevelFilter"]["highlightColor"], target.easing, time, target.duration);
								}
								if (p == "shadowAlpha") {
									bevelFilter.shadowAlpha = tweenEquations.calculateEquation(target.easing, time, target.specialInitProperties["bevelFilter"]["shadowAlpha"], target.specialProperties[s][p] - target.specialInitProperties["bevelFilter"]["shadowAlpha"], target.duration);
								}
								if (p == "shadowColor") {
									bevelFilter.highlightColor = colorChange(target.specialInitProperties["bevelFilter"]["shadowColor"], target.specialProperties["bevelFilter"]["shadowColor"], target.easing, time, target.duration);
								}								
								if (p == "quality") bevelFilter.quality = target.specialProperties[s][p];
								if (p == "knockout") bevelFilter.knockout = target.specialProperties[s][p];		
								
								// set filter array
								setFilterArray(bevelFilter,BevelFilter,newFilters);	
							}
						break;
					}
				}
			}
			if (target.target) target.target.filters = newFilters;
		}
		
		/**
		 * Set Filter in the target filters array
		 * @param	filter		Filters		Filter to add
		 * @param	filterType	Filters		Type of the Filter
		 * @param	newFilters	Array		Filter Array
		 * @return	Array
		 */
		private static function setFilterArray(filter:*,filterType:*,newFilters:Array):Array {
			// set filter array
			var d:Boolean = false;
			for (var f:* in newFilters) {
				if (newFilters[f] is filterType) {
					newFilters[f] = filter;																														
					d = true;
				}
			}
			if (!d) newFilters.push(filter);
			
			return newFilters;
		}
		/**
		 * Calculate color change
         * @param       color1					Number		Initial Color
         * @param       color2      			Number      Color to change
         * @param       transition  			String		Transition Type
         * @param       targetCurrentTime       Number      Current Time
         * @param       time                    Number      Timer
         * @return      Number			        New Color
         */
		private static function colorChange(color1:Number, color2:Number,transition:String,targetCurrentTime:Number,time:Number):uint {
			var color1R:uint = color1 >> 16 & 0xFF;
            var color1G:uint = color1 >> 8 & 0xFF;
            var color1B:uint = color1 & 0xFF;
            var color2R:uint = color2 >> 16 & 0xFF;
            var color2G:uint = color2 >> 8 & 0xFF;
            var color2B:uint = color2 & 0xFF;               
            
            var finalColorR:uint = tweenEquations.calculateEquation(transition, targetCurrentTime, color1R, color2R - color1R, time);
			if (finalColorR < 0) finalColorR = 0;
            else if (finalColorR > 255) finalColorR = 255;
            
            var finalColorG:uint = tweenEquations.calculateEquation(transition, targetCurrentTime, color1G, color2G - color1G, time);
            if (finalColorG < 0) finalColorG = 0;
            else if (finalColorG > 255) finalColorG = 255;
            
            var finalColorB:uint = tweenEquations.calculateEquation(transition, targetCurrentTime, color1B, color2B - color1B, time);
            if (finalColorB < 0) finalColorB = 0;
            else if (finalColorB > 255) finalColorB = 255;                  
			
            return (finalColorR << 16) | (finalColorG << 8) | finalColorB;
        }
	}
}